/*
 * license-updater - Copyright (c) 2012 MSF. All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 * 
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */
package br.msf.commons.netbeans.util;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import org.netbeans.api.java.classpath.ClassPath;
import org.openide.filesystems.FileObject;

/**
 * <p>Class that represents a Java package.
 *
 * @author Marcius da Silva da Fonseca (sf.marcius@gmail.com)
 * @version 1.0
 * @since license-updater-1.0
 */

public class JavaPackage implements Serializable, Comparable<JavaPackage> {

    private static final long serialVersionUID = -1386100228453543757L;
    private final ClassPath classPath;
    private final FileObject fileObject;
    private final String fullName;
    private final String displayName;
    private final boolean root;

    public JavaPackage(final ClassPath classPath, final String fullPackageName) {
        this(classPath, FileObjectUtils.getPackageFileObject(classPath, fullPackageName));
    }

    public JavaPackage(final ClassPath classPath, final FileObject packageFileObject) {
        assert classPath != null && packageFileObject != null;
        if (!packageFileObject.isFolder()) {
            throw new IllegalArgumentException("FileObject must be a folder");
        }
        if (!classPath.contains(packageFileObject)) {
            throw new IllegalArgumentException("FileObject not owned by the given classpath");
        }
        this.classPath = classPath;
        this.fileObject = packageFileObject;
        this.fullName = classPath.getResourceName(packageFileObject, '.', false);
        if (this.fullName.isEmpty()) {
            this.root = true;
            this.displayName = "< Default package >";
        } else {
            this.root = false;
            this.displayName = fullName;
        }
    }

    public FileObject getFileObject() {
        return fileObject;
    }

    public ClassPath getClassPath() {
        return classPath;
    }

    public boolean isRoot() {
        return root;
    }

    public String getFullName() {
        return fullName;
    }

    public String getDisplayName() {
        return displayName;
    }

    public boolean hasChildren() {
        Collection<FileObject> children = getChildren();
        for (FileObject child : children) {
            if (FileObjectUtils.isValidFile(child) || FileObjectUtils.isValidDir(child)) {
                return true;
            }
        }
        return false;
    }

    public boolean hasSubPackage() {
        Collection<FileObject> children = getChildren();
        for (FileObject pkg : children) {
            if (FileObjectUtils.isValidDir(pkg)) {
                return true;
            }
        }
        return false;
    }

    public boolean hasFileChildren() {
        Collection<FileObject> children = getChildren();
        for (FileObject pkg : children) {
            if (FileObjectUtils.isValidFile(pkg)) {
                return true;
            }
        }
        return false;
    }

    public Collection<FileObject> getChildren() {
        return Arrays.asList(fileObject.getChildren());
    }

    @Override
    public int compareTo(final JavaPackage javaPackage) {
        if (javaPackage == null) {
            throw new IllegalArgumentException("Cannot compare with null value.");
        }
        return getFullName().compareTo(javaPackage.getFullName());
    }

    @Override
    public boolean equals(final Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final JavaPackage other = (JavaPackage) obj;
        if (this.fileObject != other.fileObject && (this.fileObject == null || !this.fileObject.equals(other.fileObject))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 43 * hash + (this.fileObject != null ? this.fileObject.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return getFullName();
    }
}
